package DatabasePackage;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import BusinessLogic.Course;

/**
 * This is the schema for user
 */
public class CourseDBTable extends DBtable {
  public enum CourseDBTScheme {
    NAME("varchar(255)"), DESCRIPTION("varchar(2000)"), POINTS("varchar(10)"), CAPACITY("varchar(10)"), 
    GROUP_NUM("varchar(10)"), ADMIN("varchar(255)"),FULLTEXT("(NAME,DESCRIPTION)");
    private final String COLUMN_TYPE;
    
    CourseDBTScheme(String type) {
      COLUMN_TYPE = type;
    }
    
    String getType() {
      return COLUMN_TYPE;
    }
  }
  
  public CourseDBTable() {
    super(new HashMap<String, String>(), new LinkedList<String>(), new LinkedList<String>());
    // Initializing the keys
    keys.add(CourseDBTScheme.NAME.toString());
    // Initializing the scheme
    for (CourseDBTScheme column : CourseDBTScheme.values())
      scheme.put(column.toString(), column.getType());
  }
  
  /**
   * @param username
   *          the name of the user you wish to get the details of
   * @return returns a list of the fields of the selected user if it exists, if
   *         he doesn't throws an exception
   * @throws SQLException
   *           if there was problem connecting to the sql database or there was
   *           a database error
   * @throws ClassNotFoundException
   *           if connector/j was not linked
   * @throws ItemNotFoundException
   *           if there is no user with the given username
   */
  public Course getCourse(Connection con, String name) throws SQLException, ClassNotFoundException  {
    Map<String, byte[]> conditions = new HashMap<String, byte[]>();
    conditions.put(CourseDBTScheme.NAME.toString(), name.getBytes());
    List<Map<String, byte[]>> course = null;
    course = getItem(con,conditions);
    if(course.isEmpty()) return null;
    return createCourse(course.get(0));
  }

  
  public List<Course> getCoursesOfGroup(Connection con, Integer group) throws SQLException, ClassNotFoundException  {
	    Map<String, byte[]> conditions = new HashMap<String, byte[]>();
	    conditions.put(CourseDBTScheme.GROUP_NUM.toString(), group.toString().getBytes());
	    List<Map<String, byte[]>> courses = null;
	    courses = getItem(con,conditions);
	    List<Course> realCourses = new LinkedList<Course>();
	    for (Map<String, byte[]> course: courses)
	    {
	    	realCourses.add(createCourse(course));
	    }
	    return realCourses;
	  }
  
  
  public List<Course> getAllCourses(Connection con) throws SQLException, ClassNotFoundException  {
	    Map<String, byte[]> conditions = new HashMap<String, byte[]>();
	    List<Map<String, byte[]>> courses = null;
	    courses = getItem(con,conditions);
	    List<Course> realCourses = new LinkedList<Course>();
	    for (Map<String, byte[]> course: courses)
	    {
	    	realCourses.add(createCourse(course));
	    }
	    return realCourses;
	  }
  public List<Course> getAllCoursesBy(Connection con,String search) throws SQLException, ClassNotFoundException  {
	    String get = "SELECT * FROM " + dbName+" WHERE MATCH("+CourseDBTScheme.NAME.toString()+
	    		","+CourseDBTScheme.DESCRIPTION+") AGAINST(?)";
	    java.sql.PreparedStatement pstmt = con.prepareStatement(get);
	    pstmt.setBytes(1, search.getBytes());
	    ResultSet res = null;
	    List<Map<String, byte[]>> courses;
	    res = pstmt.executeQuery();
	    courses = createRow(res);
	    List<Course> realCourses = new LinkedList<Course>();
	    for (Map<String, byte[]> course: courses)
	    {
	    	realCourses.add(createCourse(course));
	    }
	    return realCourses;
  }
  
  private Course createCourse(Map<String, byte[]> c) {
    String name = new String(c.get(CourseDBTScheme.NAME.toString()));
    String description = new String (c.get(CourseDBTScheme.DESCRIPTION.toString()));
    float points = Float.parseFloat(new String(c.get(CourseDBTScheme.POINTS.toString())));
    int capacity = Integer.parseInt(new String (c.get(CourseDBTScheme.CAPACITY.toString())));
    int group = Integer.parseInt(new String (c.get(CourseDBTScheme.GROUP_NUM.toString())));
    String admin = new String(c.get(CourseDBTScheme.ADMIN.toString()));
    return new Course(name, description, points, capacity, group, admin);
  }

  /**
   * Deletes the given user from the database, if he doesn't exist, throws an
   * exception
   * 
   * @param name
   *          the username of the user to be deleted
   * @throws ItemNotFoundException
   *           if there is no user with the given username
   * @throws SQLException
   *           if there was problem connecting to the sql database or there was
   *           a database error
   * @throws ClassNotFoundException
   *           if connector/j was not linked
   */
  public void deleteCourse(Connection con,String name) throws ItemNotFoundException, SQLException, ClassNotFoundException {
    Map<String, byte[]> conditions = new HashMap<String, byte[]>();
    conditions.put(CourseDBTScheme.NAME.toString(), name.getBytes());
    removeItem(con, conditions);
  }
  
  /**
   * Adds the given user to the database, if he does exist, throws an exception
   * 
   * @param u
   *          the user record to insert
   * @throws ItemAlreadyInDBException
   *           if there is already a user with the given username in the
   *           database
   * @throws SQLException
   *           if there was problem connecting to the sql database or there was
   *           a database error
   * @throws ClassNotFoundException
   *           if connector/j was not linked
   */
  public void insertCourse(Connection con, Course c) throws ItemAlreadyInDBException, SQLException, ClassNotFoundException {
    Map<String, byte[]> record = new HashMap<String, byte[]>();
    record.put(CourseDBTScheme.NAME.toString(), c.getName().getBytes());
    record.put(CourseDBTScheme.DESCRIPTION.toString(), c.getDescription().getBytes());
    record.put(CourseDBTScheme.POINTS.toString(), Utility.castToString(c.getPoints()).getBytes());
    record.put(CourseDBTScheme.CAPACITY.toString(), Utility.castToString(c.getCapacity()).getBytes());
    record.put(CourseDBTScheme.GROUP_NUM.toString(), Utility.castToString(c.getGroup()).getBytes());
    record.put(CourseDBTScheme.ADMIN.toString(), c.getAdmin().getBytes());
    insertItem(con, record);
  }
}










